/**
 * 
 */
package tests;

import java.util.Iterator;
import java.util.Vector;

import junit.framework.TestCase;
import objects.Frm;
import objects.Message;
import objects.Trd;
import objects.User;
import DB.DataBase;
import Domain.forumManager.ForumController;
import Domain.forumProtcol.FourmProtocol;
import Domain.stompProtocol.ForumFrame;
import Domain.stompProtocol.StompClient;
import Domain.stompProtocol.StompFrame;

/**
 * @author Asaf
 */

public class FourmProtocolTest extends TestCase {
	
	/**
	 * Test method for {@link Domain.forumProtcol.FourmProtocol#getNameOfUser(java.lang.String)}.
	 */
	DataBase _database=new DataBase();
	ForumController f=new ForumController(_database);
	StompClient stompClient = new StompClient("localhost",61635);
	FourmProtocol protocol = new FourmProtocol(stompClient,f);

	private boolean searchForName(Vector<User> u,String name)
	{
		for (Iterator iterator = u.iterator(); iterator.hasNext();)
		{
			User user = (User) iterator.next();
			if (user.getUserName().equals(name))
				return true;
		}
		return false;
	}

	public void testGetNameOfUser() {

		String str="add message ; Manassen ; thread ; msg";
		assertEquals(protocol.getNameOfForum(str),"Manassen");
		assertEquals(protocol.getNameOfThread(str),"thread");
		assertEquals(protocol.getContentsOfMessage(str),"msg");
		assertEquals(str, "add message ; Manassen ; thread ; msg");
	}



	/**
	 * Test the following commands
	 * protocol :


	 *add user     V
	 *add manager  V
	 *remove user 
	 *add message  ; [name of forum] ; [name of thread ] ; [message]
	 *remove message  ; [name of forum] ; [name of thread ] ; [message] 
	 *add thread  ; [name of forum] ; [name of thread ] 
	 *add forum  ; [name of forum] 
	 *get messages  ; [name of forum] ; [name of thread ] 
	 *get threads ; [name of forum] 
	 *get forums 
	 *add friend  ; [name of user to be added]
	 *remove friend  ; [name of user to be removed]
	 *change type to manager 
	 *change type to default user 
	 *get users
	 *get type of user
	 *edit message

	 */
	String nameOfUser="Asaf";
	StompFrame s;
	String ans;
	public void testAddUser(){
		//test add user

		s=StompFrame.createSendFrame("Asaf","Asaf" , "add user");
		ans=protocol.processMessage(s);
		//System.out.println(ans);

		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		//System.err.println(this._database.getUsers());
		assertTrue(searchForName(this._database.getUsers(),"Asaf"));
		assertTrue(searchForName(this._database.getUsers(),"manager"));
		assertFalse(searchForName(this._database.getUsers(),"Dudi"));
	}
	public void testAddManager() {		
		//test add manager  ,  get type of user
		s=StompFrame.createSendFrame("Inbal","Inbal" , "add manager");
		ans=protocol.processMessage(s);
		//System.err.println(this._database.getUsers());

		assertTrue(searchForName(this._database.getUsers(),"Inbal"));


		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);


		s=StompFrame.createSendFrame("Inbal","Inbal" , "get type of user");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(), ForumFrame.TYPEManager);
	}	

	public void testAddForumChangeType() {	
		//test add forum and change type to manager

		//try to open forum as a default user
		s=StompFrame.createSendFrame("Asaf","Asaf" , "add forum ; Asaf; Cooking");
		ans=protocol.processMessage(s);
		//System.out.println(ans);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.ERRInvalidTypeOfUSer);


		//try to become a manager
		s=StompFrame.createSendFrame("Asaf","Asaf" , "change type to manager ;Asaf");
		ans=protocol.processMessage(s);
		//System.out.println(ans);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);

		//try to open forum as a manager
		s=StompFrame.createSendFrame("Asaf","Asaf" , "add forum ; Cooking");
		ans=protocol.processMessage(s);
		//System.out.println(ans);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		assertEquals(this._database.getForums().get(0).getForumName(),"Cooking");
	}
	String nameOfNotMangerUser="Dudi";
	public void testAddThread() {
		//test add thread
		//add default user
		s=StompFrame.createSendFrame("Dudi","Dudi" , "add user");

		protocol.processMessage(s);


		//default user try to add thread
		s=StompFrame.createSendFrame("Dudi","Dudi" , "add thread ; Cooking ; a");
		ans=protocol.processMessage(s);
		//System.err.println(ans  + "this one!!!");
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.ERRInvalidTypeOfUSer);
		//manager try to add thread

		s=StompFrame.createSendFrame("Asaf","Asaf" , "add thread ; Cooking ; a");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		assertEquals(_database.getThreads(_database.findFroum("Cooking")).get(0).getThreadName(), "a");
	}

	public void testAddMessage() {

		//test add message
		s=StompFrame.createSendFrame("Asaf","Asaf" , "add message ; Cooking ; a ; msg\ntitle");
		ans=protocol.processMessage(s);
		//System.err.println(_database.getMessageFromThread("Cooking", "a").get(0).getTitle());
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		assertEquals(_database.getMessageFromThread("Cooking", "a").get(0).getMessage(), "msg");
		//assertEquals(ans,nameOfUser + " publish a new message ,in thread a\n"
		//	+"in fourm Cooking\n");
	}


	public void testgetFourms() {

		//test get Forums
		s=StompFrame.createSendFrame("Asaf","Asaf" , "get forums ");

		ans=protocol.processMessage(s);

		assertEquals(protocol.getForumfrm().getType(),ForumFrame.VECTORFRM);
		@SuppressWarnings("unchecked")
		Vector<Frm> fff =(Vector<Frm>)protocol.getForumfrm().getData();
		assertEquals(fff.get(0).getForumName(), "Cooking");
	}

	public void testgetThreads() {
		//test get Threads

		s=StompFrame.createSendFrame("Asaf","Asaf" , "get threads  ; Cooking");

		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.VECTORTRD);
		Vector<Trd> ttt =(Vector<Trd>)protocol.getForumfrm().getData();
		assertEquals(ttt.get(0).getThreadName(), "a");	
	}

	public void testGetMessage() {
		//test get messages

		s=StompFrame.createSendFrame("Asaf","Asaf" , "get messages  ; Cooking ; a");
		//get messages [name of user] ; [name of forum] ; [name of thread ]
		ans=protocol.processMessage(s);

		assertEquals(protocol.getForumfrm().getType(),ForumFrame.VECTORMSG);
		Vector<Message> mm =(Vector<Message>)protocol.getForumfrm().getData();
		assertEquals(mm.get(0).getMessage(), "msg");
		//System.err.println(mm.get(0).getOwner());
	}

	public void testRemoveMessage(){
		//test remove message 

		//remove message Worng User
		s=StompFrame.createSendFrame("Dudi","Dudi" , "remove message ; Cooking ; a ; title");
		ans=protocol.processMessage(s);
		//System.err.println(ans);

		//System.err.println(protocol.getForumfrm().getType());
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.ERRInvalidTypeOfUSer);
		assertEquals(_database.getMessageFromThread("Cooking", "a").size(), 1);


		//remove message owner
		s=StompFrame.createSendFrame("Asaf","Asaf" , "remove message ; Cooking ; a ; title");
		ans=protocol.processMessage(s);
		//System.err.println(ans);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);

		assertEquals(_database.getMessageFromThread("Cooking", "a").size(), 0);

		//remove message manager
		testAddMessage();
		s=StompFrame.createSendFrame("Inbal","Inbal" , "remove message ; Cooking ; a ; title");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);

		assertEquals(_database.getMessageFromThread("Cooking", "a").size(), 0);

	}


	public void testAddFreind() {
		//add friend  ; [name of user to be added]

		s=StompFrame.createSendFrame("Asaf","Asaf" , "add friend ; Inbal");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		assertTrue(searchForName(_database.getFriendsOfUser("Asaf"), "Inbal"));
		//get friend get friends of user

		//to be deleted
		s=StompFrame.createSendFrame("Asaf","Asaf" , "add message ; Cooking ; a ; ab\nttl");
		ans=protocol.processMessage(s);




		s=StompFrame.createSendFrame("Asaf","Asaf" , "get friends of user");
		ans=protocol.processMessage(s);
		Vector<User> uu=(Vector <User>)protocol.getForumfrm().getData();
		searchForName(uu, "Inbal");
		//assertEquals(uu.get(0).get_nameOfUser(), "Inbal");



	}

	public void testRemoveFreind() {

		//System.err.println("start test remove freind"+_database.getUsers());

		//remove friend  ; [name of user to be removed]
		s=StompFrame.createSendFrame("Asaf","Asaf" , "remove friend ; Inbal");
		ans=protocol.processMessage(s);
		assertFalse(searchForName(_database.getFriendsOfUser("Asaf"), "Inbal"));
		//assertFalse(_database.findUser("Inbal").getFrindList().contains(_database.findUser("Asaf")));

		//System.err.println("end test remove freind"+_database.getUsers());


	}


	public void testChangeTypeToManager() {
		//      			change type to manager 
		s=StompFrame.createSendFrame("Dudi","Dudi" , "change type to manager");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		s=StompFrame.createSendFrame("Dudi","Dudi" , "get type of user");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(), ForumFrame.TYPEManager);




	}


	public void testChangeTypeToDefault() {

		//      			change type to default user 

		s=StompFrame.createSendFrame("Asaf","Asaf" , "change type to default user");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		s=StompFrame.createSendFrame("Asaf","Asaf" , "get type of user");
		ans=protocol.processMessage(s);
		assertEquals(protocol.getForumfrm().getType(), ForumFrame.TYPEDefaultUser);
	}



	public void testgetUsers() {	

		//      			get users
		s=StompFrame.createSendFrame("Asaf","Asaf" , "get users");
		ans=protocol.processMessage(s);
		Vector<User> u=(Vector<User>)protocol.getForumfrm().getData();
		//System.err.println(u);
		assertEquals(u.size(), 4);
		assertEquals(this._database.getUsers().size(), 4);
	}


	public void testRemoveUser() {	

		//System.err.println(_database.getUsers());
		//test remove user 
		s=StompFrame.createSendFrame("Asaf","Asaf" , "remove user Inbal;");
		ans=protocol.processMessage(s);

		assertEquals(protocol.getForumfrm().getType(),ForumFrame.ERRInvalidTypeOfUSer);

		//default user try to remove himself
		s=StompFrame.createSendFrame("Asaf","Asaf" , "remove user Asaf;");
		ans=protocol.processMessage(s);
		//System.err.println("ans is :   "+ans);
		System.err.println(protocol.getForumfrm().getType());
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		Vector<User> u=_database.getUsers();
		for (Iterator<User> iterator = u.iterator(); iterator.hasNext();)
		{
			User user = (User) iterator.next();
			if(user.getUserName().equals("Asaf"))
			{
				assertFalse(user.isActive());
			}
			else assertTrue(user.isActive());
		}


		//manager try to remove user
		s=StompFrame.createSendFrame("Dudi","Dudi" , "remove user Inbal;");
		ans=protocol.processMessage(s);
		//System.err.println("ans is :   "+ans);
		assertEquals(protocol.getForumfrm().getType(),ForumFrame.TYPESECCESS);
		u=_database.getUsers();
		for (Iterator<User> iterator = u.iterator(); iterator.hasNext();)
		{
			User user = (User) iterator.next();
			if(user.getUserName().equals("Asaf")||user.getUserName().equals("Inbal"))
			{
				assertFalse(user.isActive());
			}
			else assertTrue(user.isActive());
		}

		//assertEquals(this._database.getUsers().size(), 3);

	}

	/**/
}
